<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>

    // 工厂函数：
    /*   const person = (name) => {
        var obj = new Object(); // {}
        obj.name = name;
        return obj;
      }
  
      let a = person('刘小杰')
      console.log(a);
      let b = person('刘小杰')
      console.log(b);
      console.log(a === b);//false
  
      // 工厂函数解决了创建多个相似对象的问题。　
  // 但是每次新建的时候都需要在内部创建一个对象，如果创建十次，就会产生十个全新的对象，每一个对象之间是没有关系的，就无法搞清楚他们到底是哪个对象的实例，即无法解决对象识别的问题。
  
   */

    function Person(name) {
      this.name = name;
      // 构造函数里面的方法，不要写成箭头函数
      this.sayHi = function () {
        console.log(this.name);
      }
    }

    let a = new Person('刘小杰')
    console.log(a);//Person {name: '刘小杰'}

    let b = new Person('刘小杰')
    console.log(b); //Person {name: '刘小杰'}
    console.log(a === b);//false


    // 既解决了重复实例化的问题，又解决了对象识别的问题。创建的所有对象既是 Object 的实例，同时也是 Person的实例：

    // instanceof 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上(用于判断一个变量是否某个对象的实例)
    // console.log(a instanceof Person); // true
    // console.log(a instanceof Object);// true

    console.log(a.sayHi === b.sayHi); // false
    // 在构造函数中直接定义方法，在实例化时所有的对象都会拥有一个独立的方法，不同对象的同一个方法在不同的内存地址上，浪费内存资源，就叫方法过载。

    // 其它创建对象的方法：
    // Object.create():Object.create() 方法用于创建一个新对象，使用现有的对象来作为新创建对象的原型（prototype）。
    // Object.assign():Object.assign() 方法将所有可枚举（Object.propertyIsEnumerable() 返回 true）的自有（Object.hasOwnProperty() 返回 true）属性从一个或多个源对象复制到目标对象，返回修改后的对象。
  </script>
</body>

</html>